package moldat.utilities;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import moldat.Protein;
import moldat.SQLiteDB;

/**
 * Diese Klasse stellt einen Exporter zur Verfuegung. Mit dem Exporter koennen
 * alle Datenbank Inhalte in einen String verwandelt werden. Dieser String kann
 * dann noch zur Darstellung in einem HTML-Dokument aufbereitet werden.
 *
 * @author Marc Zoeller
 */
public class Exporter {

    private static final String GET_ALL_IDS = "SELECT uniProtID FROM protein";
    private static final String GET_GENID = "SELECT geneID FROM gene WHERE name = '";
    private static final String GET_IDS = "SELECT uniProtID FROM protein WHERE geneID = ";
    private static Exporter exporter = null;
    //TODO: Header einfuegen?? sowas wie MolDat - Namen...

    /**
     * Liefert eine Instanz der Exporter-Klasse. Diese Methode sollte anstelle
     * des Default-Konstruktors benutzt werden.
     *
     * @return eine Instanz dieser Klasse
     */
    public static Exporter getInstance() {
        //TODO: neue Informationen auch ausgeben
        if (exporter == null)
            exporter = new Exporter();
        return exporter;
    }

    /**
     * Diese Methode exportiert den gesamten Datenbank Inhalt in einen String.
     * Der String ist als Tabelle formatiert.
     *
     * @return gesamte Datenbank als String
     * @throws IOException
     * @throws SQLException
     */
    public String exportAll() throws IOException, SQLException {
        StringBuilder sb = new StringBuilder();
        sb.append("uniProtID\tprotein_name\t\t\t\t\t\tgene_name\tarrayExpress\t\t\t\t\t\t\tisoforms\t\t\t\t\t\tsynonyms\n\n");
        ResultSet rs = SQLiteDB.executeQuery(GET_ALL_IDS);
        while (rs.next()) {
            String uniProtID = rs.getString(1);
            Protein prot = SQLiteDB.getProtein(uniProtID);

            sb.append(uniProtID).append("\t");
            sb.append(prot.getName());
            for (int i = 0; i < 8 - (prot.getName().length() / 8); i++)
                sb.append("\t");
            sb.append(prot.getGene()).append("\t\t");
            if (prot.getArrayExpressUrl().isEmpty())
                sb.append("\t\t\t\t\t\t\t\t");
            else
                sb.append(prot.getArrayExpressUrl()).append("\t\t");
            sb.append(prot.getIsoforms());
            for (int i = 0; i < 7 - (prot.getIsoforms().toString().length() / 8); i++)
                sb.append("\t");

            sb.append(prot.getGeneSynonyms()).append("\n");
        }
        return sb.toString();
    }

    /**
     * Diese Methode exportiert alle Informationen aus der Datenbank, die in
     * Verbindung mit dem uebergebenen Gen Namen stehen. Die Informationen
     * werden als String zurueckgeliefert.
     *
     * @param geneName Gen Name dessen Informationen exportiert werden sollen
     * @return alle Informationen zu diesem Gen Namen
     * @throws IOException
     * @throws SQLException
     */
    public String exportGene(String geneName) throws IOException, SQLException {
        StringBuilder sb = new StringBuilder();
        sb.append("geneName:\t").append(geneName).append("\n");
        ResultSet rs = SQLiteDB.executeQuery(GET_GENID + geneName + "'");
        int geneID = 0;
        if (rs.next())
            geneID = rs.getInt(1);
        rs = SQLiteDB.executeQuery(GET_IDS + geneID);
        boolean first = true;
        while (rs.next()) {
            String uniProtID = rs.getString(1);
            Protein prot = SQLiteDB.getProtein(uniProtID);
            if (first) {
                sb.append("synonyms:\t").append(prot.getGeneSynonyms());
                sb.append("\narrayExpress:\t").append(prot.getArrayExpressUrl());
                sb.append("\n\nuniProtID\tname\t\t\t\t\t\t\t\tisoforms\n\n");
                first = false;
            }
            sb.append(uniProtID).append("\t\t");
            sb.append(prot.getName());
            for (int i = 0; i < 8 - (prot.getName().length() / 8); i++)
                sb.append("\t");
            sb.append(prot.getIsoforms()).append("\t");
        }
        return sb.toString();
    }

    /**
     * Diese Methode extrahiert alle Informationen zu einer UniProtID aus der
     * Datenbank und bereitet sie als String auf.
     *
     * @param uniProtID UniProtID zu der alle Informationen exportiert werden
     * sollen
     * @return alle Informationen zu der UniProtID
     * @throws IOException
     * @throws SQLException
     */
    public String exportProtein(String uniProtID) throws IOException, SQLException {
        StringBuilder sb = new StringBuilder();
        sb.append("uniProtID:\t").append(uniProtID);
        Protein prot = SQLiteDB.getProtein(uniProtID);
        if (prot == null)
            return sb.toString();

        sb.append("\nname:\t\t").append(prot.getName());
        sb.append("\nisoforms:\t").append(prot.getIsoforms().toString());
        sb.append("\ngene:\t\t").append(prot.getGene());
        sb.append("\ngene_synonyms:\t").append(prot.getGeneSynonyms().toString());
        sb.append("\narrayExpress:\t").append(prot.getArrayExpressUrl());

        return sb.toString();
    }
}
